package com.yy.job.console.controller;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Preconditions;
import com.yy.job.common.dao.YYJobDOExtMapper;
import com.yy.job.common.dao.YYJobDOMapper;
import com.yy.job.common.dao.YYJobStepDOMapper;
import com.yy.job.common.dao.po.YYJobDO;
import com.yy.job.common.dao.po.YYJobDOExample;
import com.yy.job.common.dao.po.YYJobStepDO;
import com.yy.job.common.enums.JobStatusEnum;
import com.yy.job.common.enums.JobStepStatusEnum;
import com.yy.job.common.service.impl.YYJobStepServiceImpl;
import com.yy.job.common.utils.BaseResult;
import com.yy.job.common.utils.IPUtils;
import com.yy.job.common.utils.PagingParam;
import com.yy.job.console.converter.JobStepViewConverter;
import com.yy.job.console.converter.JobViewConverter;
import com.yy.job.console.dto.JobSearchParamDTO;
import com.yy.job.console.dto.JobStepView;
import com.yy.job.console.dto.JobView;
import com.yy.job.console.dto.PageDTO;
import com.yy.job.console.service.JobConsoleServicve;
import com.yy.job.console.service.JobStepConsoleService;
import com.yy.job.console.utils.BaseResultUtil;
import com.yy.job.console.utils.CommonErrorCode;
import com.yy.job.console.utils.JobConsoleConstants;

@RestController
@RequestMapping({ JobConsoleConstants.YY_JOB_JOB_PREFIX })
public class YYJobController {

	private final Logger log = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private YYJobDOExtMapper yyJobDOExtMapper;

	@Autowired
	private YYJobDOMapper yyJobDOMapper;

	@Autowired
	private YYJobStepDOMapper yyJobStepDOMapper;

	@Autowired
	private JobConsoleServicve jobConsoleServicve;

	@Autowired
	private YYJobStepServiceImpl jobStepServiceImpl;

	@Autowired
	private JobStepConsoleService jobStepConsoleService;

	/**
	 * 根据查询条件查询job数据
	 * 
	 * @param searchParam
	 * @return
	 */
	@RequestMapping(value = { "/listJob" }, method = { RequestMethod.POST })
	public BaseResult<PageDTO<JobView>> listJob(@RequestBody JobSearchParamDTO searchParam) {
		log.info("JobController.listJob param={}", JSON.toJSON(searchParam));
		Preconditions.checkArgument((searchParam != null), "查询参数不能为空");
		Preconditions.checkArgument((searchParam.getPageSize().intValue() <= 100), "查询参数不正确");

		PageDTO<JobView> result = new PageDTO<>(searchParam.getPageSize(), searchParam.getCurrentPage());
		result.setStartRow(result.calStartRow());

		// 分页查询数据
		PagingParam buildPagingParam = searchParam.buildPagingParam();
		Integer countPageJob = this.yyJobDOExtMapper.countPageJob(buildPagingParam);
		result.setTotalItem(countPageJob);
		if (countPageJob != 0) {
			List<YYJobDO> listPageJob = this.yyJobDOExtMapper.listPageJob(buildPagingParam);
			result.setResultList(JobViewConverter.listConvert(listPageJob));
		}

		return BaseResultUtil.success(result);
	}

	/**
	 * 查询步骤列表
	 * 
	 * @param jobId
	 * @return
	 */
	@RequestMapping(value = { "/listStep" }, method = { RequestMethod.GET })
	public BaseResult<List<JobStepView>> listStep(@RequestParam("jobId") Long jobId) {
		Preconditions.checkArgument((jobId != null), "查询参数jobId不能为空");

		List<YYJobStepDO> selectStepsByJobId = jobStepServiceImpl.selectStepsByJobId(jobId);
		// 排序
		Collections.sort(selectStepsByJobId, new Comparator<YYJobStepDO>() {
			public int compare(YYJobStepDO step1, YYJobStepDO step2) {
				if (step1.getStepOrder() == null && step2.getStepOrder() == null)
					return 0;
				if (step1.getStepOrder() == null)
					return 1;
				if (step2.getStepOrder() == null)
					return -1;
				return step1.getStepOrder().compareTo(step2.getStepOrder());
			}
		});
		return BaseResultUtil.success(JobStepViewConverter.listConvert(selectStepsByJobId));
	}

	/**
	 * 关闭任务
	 * 
	 * @param jobIds
	 * @return
	 */
	@RequestMapping(value = { "/batchCloseJob" }, method = { RequestMethod.GET })
	public BaseResult<Integer> batchCloseJob(@RequestParam("jobIds") List<Long> jobIds) {
		log.info("batchDelJob,{},{}", jobIds, getModifier());
		Preconditions.checkArgument(CollectionUtils.isNotEmpty(jobIds), "参数jobIds不能为空");
		Preconditions.checkArgument((jobIds.size() <= 50), "一次性删除任务数不能超过50");

		// 校验状态
		YYJobDOExample example = new YYJobDOExample();
		example.createCriteria().andIdIn(jobIds).andIsDeletedEqualTo("N");
		
		List<YYJobDO> selectByExample = yyJobDOMapper.selectByExample(example);
		List<YYJobDO> collect = selectByExample.stream().filter(e -> e.getJobStatus().equals(JobStatusEnum.FAIL.getCode()))
				.collect(Collectors.toList());
		if (CollectionUtils.isEmpty(collect)) {
			return BaseResultUtil.fail(CommonErrorCode.FAIL, null, "没有可关闭的任务");
		}

		// 修改数据
		Integer batchCloseJob = jobConsoleServicve.batchCloseJob(jobIds, getModifier());
		return BaseResultUtil.success(batchCloseJob);
	}

	/**
	 * 重启任务
	 * 
	 * @param jobIds
	 * @return
	 */
	@RequestMapping(value = { "/batchResetJob" }, method = { RequestMethod.GET })
	public BaseResult<Integer> batchResetJob(@RequestParam("jobIds") List<Long> jobIds) {
		log.info("batchResetJob,jobIds={},modifier={}", jobIds, getModifier());
		Preconditions.checkArgument(CollectionUtils.isNotEmpty(jobIds), "参数jobIds不能为空");
		Preconditions.checkArgument((jobIds.size() <= 50), "一次性重置任务数不能超过50");

		// 校验状态
		YYJobDOExample example = new YYJobDOExample();
		example.createCriteria().andIdIn(jobIds).andIsDeletedEqualTo("N");
		List<YYJobDO> selectByExample = yyJobDOMapper.selectByExample(example);
		List<YYJobDO> collect = selectByExample.stream().filter(e -> e.getJobStatus().equals(JobStatusEnum.FAIL.getCode()))
				.collect(Collectors.toList());
		if (CollectionUtils.isEmpty(collect)) {
			return BaseResultUtil.fail(CommonErrorCode.FAIL, null, "没有可重启的任务");
		}

		// 修改数据
		Integer batchCloseJob = jobConsoleServicve.batchResetJob(jobIds, getModifier());
		return BaseResultUtil.success(batchCloseJob);
	}

	/**
	 * 跳过步骤
	 * 
	 * @param taskId
	 * @return
	 */
	@RequestMapping(value = { "/skipStep" }, method = { RequestMethod.GET })
	public BaseResult<Integer> skipStep(@RequestParam("stepId") Long stepId) {
		log.info("stepId,{},{}", stepId, getModifier());
		Preconditions.checkArgument((stepId != null), "参数stepId不能为空");

		YYJobStepDO jobStepDO = this.yyJobStepDOMapper.selectByPrimaryKey(stepId);
		YYJobDO jobDO = this.yyJobDOMapper.selectByPrimaryKey(jobStepDO.getJobId());

		// 不是FAIL的任务，不能跳过
		if (!JobStatusEnum.FAIL.getCode().equals(jobDO.getJobStatus())
				|| !JobStepStatusEnum.FAIL.getCode().equals(jobStepDO.getStepStatus())) {
			return BaseResultUtil.fail(CommonErrorCode.FAIL, null, "任务状态不支持跳过步骤");
		}
		// 唯一步骤不能跳过
		List<YYJobStepDO> jobSteps = this.jobStepServiceImpl.selectStepsByJobId(jobStepDO.getJobId());
		if (CollectionUtils.isEmpty(jobSteps) || jobSteps.size() == 1) {
			return BaseResultUtil.fail(CommonErrorCode.FAIL, null, "唯一步骤不支持跳过");
		}

		Integer skipStep = jobStepConsoleService.skipStep(jobStepDO, getModifier());
		return BaseResultUtil.success(skipStep);
	}

	private String getModifier() {
		return IPUtils.getLocalIP();
	}

}
